package gbench.appdemo.mall.erp;

import static gbench.common.matlib.MatlibCanvas.println;
import static gbench.common.matlib.rdd.BasePair.bp;
import static gbench.common.tree.LittleTree.IRecord.A;
import static gbench.common.tree.LittleTree.IRecord.CONS;
import static gbench.common.tree.LittleTree.IRecord.REC;
import static gbench.common.tree.LittleTree.IRecord.rb;
import static gbench.common.tree.LittleTree.Term.FT;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

import gbench.appdemo.mall.erp.site.IInfoSite;
import gbench.appdemo.mall.erp.site.InfoSite;
import gbench.common.matlib.MatlibCanvas.XVec;
import gbench.common.tree.LittleTree.IRecord;
import gbench.common.tree.LittleTree.Jdbc;
import gbench.commonApp.jdbc.IJdbcApp;

/**
 * j简单的ERP
 * @author gbench
 *
 */
public class MyPlatform {
    
    /**
     * 数据初始化
     */
    public void initialize() {
        final var partA = erpApp.getEnterprise(1, true);
        final var partB = erpApp.getEnterprise(2, true);
        final var storeA = partA.getStore();
        final var storeB = partB.getStore();
        erpApp.dataApp.sqlqueryS("select * from t_house").collect(XVec.xveclc()).shuffle().head(2).forEach(e -> {
            storeA.addHouse(storeA.createHouse(e));
            storeB.addHouse(storeA.createHouse(e));
        });
        final var productPrices = erpApp.getProductS().map(pct->bp(pct, erpApp.financeApp.rmb(pct.getPrice().getAmount()))).collect(XVec.xveclc()); // 产品价格
        var catalog = partA.buildCatalog(REC("name", "我的比萨", "symbol","PIZZA"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        catalog = partA.buildCatalog(REC("name", "我的饺子", "symbol","JIAOZI"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        catalog = partA.buildCatalog(REC("name", "我的包子", "symbol","BAOZI"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        catalog = partA.buildCatalog(REC("name", "我的煎饼", "symbol","JIANBING"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        catalog = partA.buildCatalog(REC("name", "我的馄饨", "symbol","HUNDUN"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        catalog = partA.buildCatalog(REC("name", "我的汤圆", "symbol","TANGYUAN"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        catalog = partB.buildCatalog(REC("name", "我的产品", "symbol","CHANPIN"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        partA.setDefaultCatalog(catalog); // 设置默认产品目录
        partA.getDefaultCatalog().getPriceQuotes().forEach(e -> {
            println(e);
        });
        
        partB.buildCatalog(REC("name","我的元宵","symbol","JIAOZI"), 0.2, 0.17, productPrices.shuffle().resize(10).list()); // 创建产品目录
        
        final var catalog_query = erpApp.dataApp.tbl2maybe_rec_f("t_catalog");
        final var opt = catalog_query.apply(REC("name","我的饺子")).map(e->erpApp.new Catalog(e));
        if(opt.isPresent()) {
            println("产品目录:",opt.get(),opt.get().getId());
        }
        
        println("默认的catalog",partA.getCatalog(partA.getDefaultCatalog().getId()));
    }
    
    /**
     * 金融数据准备
     */
    public void finance_initialize() {
        
        final Consumer<List<String>> sql_execute_batch  = sqls -> { // 批量的 sql 语句执行
            erpApp.dataApp.withTransaction( sess -> {
                for(var sql:sqls) sess.sql2execute(sql);
            });
        };
        
        final Consumer<String> sql_execute  = sql -> { // sql 语句执行
            sql_execute_batch.accept(IRecord.L(sql));
        };
        
        final Function<IRecord,String> coa_insert_sql = rec -> { // id, code , name, type, remarks
            final var flds = "id,code,name,type,path,price,description,remarks";
            final Object[] aa = CONS(flds,Stream.of("id,code,name,type,name,remarks".split(",")).map(rec::get).toArray(String[]::new)); // 注意这里把 description 对应到了 name
            final var line = FT("insert into t_coa($0) values ('$1','$2','$3','$4','D:/sliced/files/products/valuables/gold.jpg','1.0','$5','$6')",aa);
            return line;
        };
        
        Stream.of( // 数据清空
            "delete from t_coa where id < 0", // 清空 中央银行账户
            "delete from t_coa where id > 10000", // 清空 企业存款 账户
            "delete from t_entity_item_rel where name = 't_transaction/t_coa'" // 清空 记账分录
        ).peek(System.out::println).forEach(sql_execute); // 清空数据

        println("------------------------------------------");

        Stream.of(// 创建账户
            // 中央银行 账户
            A("-1", "9000.0", "货币发行", "负债类", "中央银行科目"), // 货币发行
            A("-2", "9001.0", "人民币-M0", "资产类", "中央银行科目"), // 人民币-M0 账户
            A("-3", "9002.0", "银行准备金", "负债类", "中央银行科目"), // 银行准备金
            A("-4", "9003.0", "客户存款", "负债类", "银行科目"), // 客户存款
            // 银行准备金 账户
            A("-90020015", "9002.15", "银行准备金-工商银行", "负债类", "中央银行科目"), // 商业银行在央行开户 - 工商银行
            A("-90020029", "9002.29", "银行准备金-农业银行", "负债类", "中央银行科目"), // 商业银行在央行开户 - 农业银行
            // 企业存款 账户
            A("90030001", "9003.1", "客户存款-沃尔玛", "资产类", "银行科目-客户存款"), // 企业开户 银行存款-沃尔玛 , id = 基本账户+企业id
            A("90030002", "9003.2", "客户存款-国家电网", "资产类", "银行科目-客户存款") // 企业开户 银行存款-国家电网 , id = 基本账户+企业id
        ).map(rb("id,code,name,type,remarks")::build).map(coa_insert_sql).peek(System.out::println)
        .forEach(sql_execute); // 创建账户
    } // finance_initialize
    
    /**
     * withTransaction 函数
     * 
     * @param <T>    结果类型
     * @param mapper erp->T 结果映射
     * @return T
     */
    public <T> T withTransaction(final Function<MyERPApp, T> mapper) {

        return mapper.apply(erpApp);
    }
    
    /*
     * 信息点
     */
    public IInfoSite infoSiteOf(final String home) {
        return new InfoSite(erpApp,home);
    }
    
    /*
     * 信息点
     */
    public IInfoSite infoSiteOf(final Integer infositeid) {
        final var config = this.getInfoSiteConfig(infositeid);
        final var infoSite = this.infoSiteOf(config.str("home"));// 信息站
        return infoSite;
    }
    
    /**
     * 获取infosite 的基础地址 ( 不管 何种 infoSiteId 统一 返回 资源路径 D:/sliced/tmp/erpsite/product ）
     * 
     * @param infoSiteId infosite的id 信息资源路径的id
     * @return {home,media_server_url}
     */
    public IRecord getInfoSiteConfig(final int infoSiteId) {
        return REC("home","D:/sliced/tmp/erpsite/product","media_server_url","http://localhost:8082/mall/media/streamfile?file=");
    }

    final MysqlDatabase database = IJdbcApp.newNspebDBInstance("db3.sql", MysqlDatabase.class); // 创建数据库像
    final IRecord proxy = database.getProxy(); // 提取代理对象
    final Jdbc jdbc = proxy.findOne(Jdbc.class); // 获取jdbc对象
    final MyERPApp erpApp = new MyERPApp(jdbc);
}
